package com.glw.sso.platform.common.exception;


import com.glw.sso.platform.common.annotation.ErrorMessage;
import lombok.Getter;
import lombok.Setter;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 公用异常类
 * Created by Ken on 2017/9/19.
 */
public abstract class BaseException extends RuntimeException {

    @Getter
    private int code;

    @Getter
    @Setter
    private String message;

    @Getter
    @Setter
    private Object data;

    @Getter
    @Setter
    private String moreInfo;

    /**
     * (线程安全) 按异常代码分类存储的
     */
    private static ConcurrentHashMap<Class, ConcurrentHashMap<Object, String>> codeMaps = new ConcurrentHashMap<>();


    public BaseException(int code, Object... args) {
        this.code = code;

        init(args);
    }

    /**
     * 异常代码类
     *
     * @return
     */
    public abstract Class getCodeClass();

    private void init(Object... args) {
        ConcurrentHashMap<Object, String> innerMap = codeMaps.get(getCodeClass());

        if (innerMap == null) {
            //如果本异常代码类没有初始化, 则进行构建
            innerMap = new ConcurrentHashMap<>();
            codeMaps.put(getCodeClass(), innerMap);
            //进行变量扫描
            ConcurrentHashMap<Object, String> finalInnerMap = innerMap;
            Arrays.stream(getCodeClass().getDeclaredFields())
                    .forEach(field -> {
                        //遍历每个本异常代码类声明的变量, 存入 map - key:变量的值(即错误码) value: @ErrorMessage注解的内容
                        try {
                            ErrorMessage annotation = field.getAnnotation(ErrorMessage.class);
                            finalInnerMap.put(field.get("value"), annotation.value());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
        }

        String pattern = innerMap.get(code);
        if (args != null && args.length > 0) {
            message = MessageFormat.format(pattern, args);
        } else {
            message = pattern;
        }
    }
}
